// store/modules/area/index.ts
import { defineStore } from 'pinia'
import { computed, ref } from 'vue'

import { CacheManager } from '@/utils/cache-manager'

import { type AreaApiResponse, getAreaList } from './api'

// 按父ID分组的数据缓存
interface AreaGroupCache {
  [parentId: string]: AreaApiResponse[]
}

// 树形结构的地区数据
interface AreaTreeNode extends AreaApiResponse {
  children?: AreaTreeNode[]
}

export const useAreaStore = defineStore('area', () => {
  // 原始一维数据
  const rawAreas = ref<AreaApiResponse[]>([])
  // 按父ID分组存储数据
  const areaGroups = ref<AreaGroupCache>({})
  // 按ID索引的数据（用于快速查找）
  const areaMap = ref<Map<string, AreaApiResponse>>(new Map())
  // 按code索引的数据（用于快速查找）
  const areaCodeMap = ref<Map<string, AreaApiResponse>>(new Map())
  // 存储省份列表（level 3）
  const provinces = ref<AreaApiResponse[]>([])
  // 树形结构数据
  const areaTree = ref<AreaTreeNode[]>([])
  const loading = ref(false)
  // 数据是否已初始化
  const initialized = ref(false)

  // 创建缓存管理器
  const areaManager = new CacheManager<AreaApiResponse[]>({
    fetcher: async () => {
      const response = await getAreaList()
      // 从响应对象中提取data字段
      return response.model || []
    },
    dataRef: rawAreas,
    loadingRef: loading,
    transform: (data: AreaApiResponse[]) => {
      // 处理并存储数据
      processAreaData(data)
      initialized.value = true
      return data
    },
    validator: (data: AreaApiResponse[]) => Array.isArray(data) && data.length > 0,
  })

  // 处理地区数据的核心方法
  const processAreaData = (areas: AreaApiResponse[]) => {
    // 清空所有缓存
    areaGroups.value = {}
    areaMap.value.clear()
    areaCodeMap.value.clear()
    provinces.value = []
    areaTree.value = []
    // 1. 构建索引映射
    areas.forEach(area => {
      areaMap.value.set(area.node, area)
      areaCodeMap.value.set(area.code, area)
    })

    // 2. 按父ID分组
    areas.forEach(area => {
      const parentId = area.parentId
      if (!areaGroups.value[parentId]) {
        areaGroups.value[parentId] = []
      }
      areaGroups.value[parentId].push(area)
    })

    // 3. 提取省份列表
    provinces.value = areas.filter(area => area.level === 3)

    // 4. 构建树形结构
    areaTree.value = buildAreaTree(areas)

    // 5. 排序
    sortAreaData()
  }

  // 构建树形结构
  const buildAreaTree = (areas: AreaApiResponse[]): AreaTreeNode[] => {
    const tree: AreaTreeNode[] = []
    const nodeMap = new Map<string, AreaTreeNode>()

    // 创建所有节点
    areas.forEach(area => {
      const node: AreaTreeNode = {
        ...area,
        children: [],
      }
      nodeMap.set(area.node, node)
    })
    console.log('nodeMap', nodeMap)
    // 建立父子关系
    areas.forEach(area => {
      const node = nodeMap.get(area.node)!
      if (area.level === 3) {
        // 根节点（省份）
        tree.push(node)
      } else {
        // 子节点
        const parent = nodeMap.get(area.parentId)
        if (parent) {
          if (!parent.children) {
            parent.children = []
          }
          parent.children.push(node)
        }
      }
    })

    return tree
  }

  // 排序数据
  const sortAreaData = () => {
    // 排序省份
    provinces.value.sort((a, b) => a.sort - b.sort)

    // 排序分组数据
    Object.values(areaGroups.value).forEach(group => {
      group.sort((a, b) => a.sort - b.sort)
    })

    // 递归排序树形结构
    const sortTree = (nodes: AreaTreeNode[]) => {
      nodes.sort((a, b) => a.sort - b.sort)
      nodes.forEach(node => {
        if (node.children && node.children.length > 0) {
          sortTree(node.children)
        }
      })
    }
    sortTree(areaTree.value)
  }

  // 获取所有地区数据
  const getAreas = async (options?: { forceRefresh?: boolean }) => {
    if (!initialized.value || options?.forceRefresh) {
      return areaManager.getData(options)
    }
    return rawAreas.value
  }

  // 获取指定省份的城市列表
  const getCities = (provinceId: string) => {
    return computed(() => {
      return areaGroups.value[provinceId]?.filter(area => area.level === 4) || []
    })
  }

  // 获取指定城市的区县列表
  const getDistricts = (cityId: string) => {
    return computed(() => {
      return areaGroups.value[cityId]?.filter(area => area.level === 5) || []
    })
  }

  // 根据ID获取地区详情（优化性能）
  const getAreaById = (id: string) => {
    return computed(() => {
      return areaMap.value.get(id)
    })
  }

  // 根据编码获取地区（优化性能）
  const getAreaByCode = (code: string) => {
    return computed(() => {
      return areaCodeMap.value.get(code)
    })
  }

  // 获取地区完整名称（省市区）
  const getFullAreaName = (areaId: string) => {
    const area = areaMap.value.get(areaId)
    if (!area) return ''

    const names: string[] = [area.name]
    let current = area

    while (current.parentId && current.parentId !== '0') {
      const parent = areaMap.value.get(current.parentId)
      if (parent) {
        names.unshift(parent.name)
        current = parent
      } else {
        break
      }
    }

    return names.join('/')
  }

  // 获取地区路径（返回ID数组）
  const getAreaPath = (areaId: string): string[] => {
    const path: string[] = []
    let current = areaMap.value.get(areaId)

    while (current) {
      path.unshift(current.node)
      if (current.parentId === '0') break
      current = areaMap.value.get(current.parentId)
    }

    return path
  }

  // 获取级联选择器数据
  const getCascadeOptions = computed(() => {
    return areaTree.value.map(province => ({
      value: province.node,
      label: province.name,
      level: province.level,
      code: province.code,
      disabled: province.enable === '2',
      children:
        province.children?.map(city => ({
          value: city.node,
          label: city.name,
          level: city.level,
          code: city.code,
          disabled: province.enable === '2',
          children:
            city.children?.map(district => ({
              value: district.node,
              label: district.name,
              level: district.level,
              code: district.code,
              disabled: province.enable === '2',
            })) || [],
        })) || [],
    }))
  })

  // 获取指定层级的级联数据
  const getCascadeOptionsToLevel = (maxLevel: number) => {
    return computed(() => {
      return areaTree.value.map(province => {
        const result: any = {
          value: province.node,
          label: province.name,
          level: province.level,
          code: province.code,
        }

        if (maxLevel >= 4 && province.children) {
          result.children = province.children.map(city => {
            const cityResult: any = {
              value: city.node,
              label: city.name,
              level: city.level,
              code: city.code,
            }

            if (maxLevel >= 5 && city.children) {
              cityResult.children = city.children.map(district => ({
                value: district.node,
                label: district.name,
                level: district.level,
                code: district.code,
              }))
            }

            return cityResult
          })
        }

        return result
      })
    })
  }

  // 搜索地区（支持模糊搜索）
  const searchAreas = (keyword: string, level?: number) => {
    const results = rawAreas.value.filter(area => {
      const matchName = area.name.includes(keyword)
      const matchLevel = level ? area.level === level : true
      return matchName && matchLevel
    })

    return results.map(area => ({
      ...area,
      fullName: getFullAreaName(area.node),
    }))
  }

  // 根据父ID获取子区域
  const getChildrenById = (parentId: string) => {
    return computed(() => {
      return areaGroups.value[parentId] || []
    })
  }

  // 检查区域是否存在
  const hasArea = (id: string) => {
    return areaMap.value.has(id)
  }

  // 获取区域层级路径名称
  const getAreaPathNames = (areaId: string): string[] => {
    const path = getAreaPath(areaId)
    return path.map(id => areaMap.value.get(id)?.name || '').filter(Boolean)
  }

  // 重置数据
  const reset = () => {
    rawAreas.value = []
    areaGroups.value = {}
    areaMap.value.clear()
    areaCodeMap.value.clear()
    provinces.value = []
    areaTree.value = []
    initialized.value = false
    areaManager.reset()
  }

  return {
    // 状态
    loading,
    initialized,
    provinces,
    areaTree,

    // 方法
    getAreas,
    getCities,
    getDistricts,
    getAreaById,
    getAreaByCode,
    getFullAreaName,
    getAreaPath,
    getAreaPathNames,
    getCascadeOptions,
    getCascadeOptionsToLevel,
    searchAreas,
    getChildrenById,
    hasArea,
    reset,
  }
})
